package dao;

// 通过这个类来完成 数据库建立连接 和 资源回收
import org.sqlite.SQLiteDataSource;

import javax.sql.DataSource;
import java.sql.*;

public class DBUtil {
    // 使用 单例模式 来提供 dataSource
    private static volatile DataSource dataSource = null; // 加入 volatile 可以禁止 指令重排序

    // 创建数据源：DataSource
    public static DataSource getDataSource() {
        /*
        当前的单例模式在多线程环境下存在安全问题，当2个线程同时调用 getDataSource，可能导致创建了
        多个 DataSource 实例，防止多线程情况下安全问题，进行加锁
         */
        if (dataSource == null) {  // 第1个 if 判断是否要加锁
            // 给当前类加锁，作用于 DBUtil 类的所有对象实例,进入同步代码前要获得 当前 class 的锁。
            synchronized (DBUtil.class) {
                if(dataSource == null) {  // 第2个 if 判断是否要创建实例
                    dataSource = new SQLiteDataSource();
                    ((SQLiteDataSource)dataSource).setUrl("jdbc:sqlite:" +
                            "//F:/filePath/sqlite3/fileSearch.db");
                }
            }
        }
        return dataSource;
    }

    // 建立连接
    public static Connection getConnection() throws SQLException {
        return getDataSource().getConnection();
    }

    // 关闭资源
    // PreparedStatement 接口是 Statement 的子接口，它表示一条预编译过的 SQL 语句
    public static void close(Connection connection, Statement
            statement, ResultSet resultSet) {
        // 将 3 个判断分开进行 try catch，是为了 不让某一个出现异常 而影响其他参数的关闭
        if(resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}
